﻿using Engine;
using GameEntitySystem;
using System;
using System.Linq;
using Game;
namespace Xmod
{
	public class XmodPlayerData:PlayerData
	{		
		public XmodPlayerData(Project project):base(project)
		{
			m_stateMachine.m_states.Clear();
			m_stateMachine.AddState("FirstUpdate", null, delegate
			{
				if (ComponentPlayer != null)
				{
					UpdateSpawnDialog(string.Format(LanguageControl.Get(fName, 4), Name, MathUtils.Floor(Level)), null, 0f, resetProgress: true);
					m_stateMachine.TransitionTo("WaitForTerrain");
				}
				else
				{
					m_stateMachine.TransitionTo("PrepareSpawn");
				}
			}, null);
			m_stateMachine.AddState("PrepareSpawn", delegate
			{
				if (SpawnPosition == Vector3.Zero)
				{
					if (SubsystemPlayers.GlobalSpawnPosition == Vector3.Zero)
					{
						PlayerData playerData = SubsystemPlayers.PlayersData.FirstOrDefault((PlayerData pd) => pd.SpawnPosition != Vector3.Zero);
						if (playerData != null)
						{
							if (playerData.ComponentPlayer != null)
							{
								SpawnPosition = playerData.ComponentPlayer.ComponentBody.Position;
								m_spawnMode = SpawnMode.InitialNoIntro;
							}
							else
							{
								SpawnPosition = playerData.SpawnPosition;
								m_spawnMode = SpawnMode.InitialNoIntro;
							}
						}
						else
						{
							SpawnPosition = m_subsystemTerrain.TerrainContentsGenerator.FindCoarseSpawnPosition();
							m_spawnMode = SpawnMode.InitialIntro;
						}
						SubsystemPlayers.GlobalSpawnPosition = SpawnPosition;
					}
					else
					{
						SpawnPosition = SubsystemPlayers.GlobalSpawnPosition;
						m_spawnMode = SpawnMode.InitialNoIntro;
					}
				}
				else
				{
					m_spawnMode = SpawnMode.Respawn;
				}
				if (m_spawnMode == SpawnMode.Respawn)
				{
					UpdateSpawnDialog(string.Format(LanguageControl.Get(fName, 2), Name, MathUtils.Floor(Level)), LanguageControl.Get(fName, 3), 0f, resetProgress: true);
				}
				else
				{
					UpdateSpawnDialog(string.Format(LanguageControl.Get(fName, 4), Name, MathUtils.Floor(Level)), null, 0f, resetProgress: true);
				}
				m_subsystemTerrain.TerrainUpdater.SetUpdateLocation(PlayerIndex, SpawnPosition.XZ, 0f, 64f);
				m_terrainWaitStartTime = Time.FrameStartTime;
			}, delegate
			{
				if (Time.PeriodicEvent(0.1, 0.0))
				{
					float updateProgress2 = m_subsystemTerrain.TerrainUpdater.GetUpdateProgress(PlayerIndex, 0f, 64f);
					UpdateSpawnDialog(null, null, 0.5f * updateProgress2, resetProgress: false);
					if (!(updateProgress2 < 1f) || !(Time.FrameStartTime - m_terrainWaitStartTime < 15.0))
					{
						switch (m_spawnMode)
						{
							case SpawnMode.InitialIntro:
								SpawnPosition = FindIntroSpawnPosition(SpawnPosition.XZ);
								break;
							case SpawnMode.InitialNoIntro:
								SpawnPosition = FindNoIntroSpawnPosition(SpawnPosition, respawn: false);
								break;
							case SpawnMode.Respawn:
								SpawnPosition = FindNoIntroSpawnPosition(SpawnPosition, respawn: true);
								break;
							default:
								throw new InvalidOperationException(LanguageControl.Get(fName, 5));
						}
						m_stateMachine.TransitionTo("WaitForTerrain");
					}
				}
			}, null);
			m_stateMachine.AddState("WaitForTerrain", delegate
			{
				m_terrainWaitStartTime = Time.FrameStartTime;
				Vector2 center = (ComponentPlayer != null) ? ComponentPlayer.ComponentBody.Position.XZ : SpawnPosition.XZ;
				m_subsystemTerrain.TerrainUpdater.SetUpdateLocation(PlayerIndex, center, MathUtils.Min(m_subsystemSky.VisibilityRange, 64f), 0f);
			}, delegate
			{
				if (Time.PeriodicEvent(0.1, 0.0))
				{
					float updateProgress = m_subsystemTerrain.TerrainUpdater.GetUpdateProgress(PlayerIndex, MathUtils.Min(m_subsystemSky.VisibilityRange, 64f), 0f);
					UpdateSpawnDialog(null, null, 0.5f + 0.5f * updateProgress, resetProgress: false);
					if ((updateProgress >= 1f && Time.FrameStartTime - m_terrainWaitStartTime > 2.0) || Time.FrameStartTime - m_terrainWaitStartTime >= 15.0)
					{
						if (ComponentPlayer == null)
						{
							SpawnPlayer(SpawnPosition, m_spawnMode);
							foreach (var item in XmodComponentHealth.slotsCaches)
							{
								if (item.inventoryType == InventoryType.ComponentClothing)
								{
									foreach (var obj in item.m_clothes) {
										ComponentPlayer.ComponentClothing.SetClothes(obj.Key,obj.Value);
									}
								}
								else if (item.inventoryType == InventoryType.ComponentCraftingTable)
								{
									ComponentCraftingTable componentCraftingTable = ComponentPlayer.Entity.FindComponent<ComponentCraftingTable>();
									if (componentCraftingTable != null) {
										componentCraftingTable.RemoveSlotItems(item.Index, componentCraftingTable.GetSlotCount(item.Index));
										componentCraftingTable.AddSlotItems(item.Index, item.Value, item.Count);
									}
								}
								else {
									ComponentPlayer.ComponentMiner.Inventory.RemoveSlotItems(item.Index, ComponentPlayer.ComponentMiner.Inventory.GetSlotCount(item.Index));
									ComponentPlayer.ComponentMiner.Inventory.AddSlotItems(item.Index, item.Value, item.Count);
								}
							}
							XmodComponentHealth.slotsCaches.Clear();
						}
						m_stateMachine.TransitionTo("Playing");
					}
				}
			}, null);
			m_stateMachine.AddState("Playing", delegate
			{
				HideSpawnDialog();
			}, delegate
			{
				if (ComponentPlayer == null)
				{
					m_stateMachine.TransitionTo("PrepareSpawn");
				}
				else if (m_playerDeathTime.HasValue)
				{
					m_stateMachine.TransitionTo("PlayerDead");
				}
				else if (ComponentPlayer.ComponentHealth.Health <= 0f)
				{
					m_playerDeathTime = Time.RealTime;
				}
			}, null);
			m_stateMachine.AddState("PlayerDead", delegate
			{
				GameWidget.ActiveCamera = GameWidget.FindCamera<DeathCamera>();
				if (ComponentPlayer != null)
				{
					string text = ComponentPlayer.ComponentHealth.CauseOfDeath;
					if (string.IsNullOrEmpty(text))
					{
						text = LanguageControl.Get(fName, 12);
					}
					string arg = string.Format(LanguageControl.Get(fName, 13), text);
					if (m_subsystemGameInfo.WorldSettings.GameMode == GameMode.Cruel)
					{
						ComponentPlayer.ComponentGui.DisplayLargeMessage(LanguageControl.Get(fName, 6), string.Format(LanguageControl.Get(fName, 7), arg, LanguageControl.Get("GameMode", m_subsystemGameInfo.WorldSettings.GameMode.ToString())), 30f, 1.5f);
					}
					else if (m_subsystemGameInfo.WorldSettings.GameMode == GameMode.Adventure && !m_subsystemGameInfo.WorldSettings.IsAdventureRespawnAllowed)
					{
						ComponentPlayer.ComponentGui.DisplayLargeMessage(LanguageControl.Get(fName, 6), string.Format(LanguageControl.Get(fName, 8), arg), 30f, 1.5f);
					}
					else
					{
						ComponentPlayer.ComponentGui.DisplayLargeMessage(LanguageControl.Get(fName, 6), string.Format(LanguageControl.Get(fName, 9), arg), 30f, 1.5f);
					}
				}
				Level = MathUtils.Max(MathUtils.Floor(Level / 2f), 1f);
			}, delegate
			{
				if (ComponentPlayer == null)
				{
					m_stateMachine.TransitionTo("PrepareSpawn");
				}
				else if (Time.RealTime - m_playerDeathTime.Value > 1.5 && !DialogsManager.HasDialogs(ComponentPlayer.GuiWidget) && ComponentPlayer.GameWidget.Input.Any)
				{
					if (m_subsystemGameInfo.WorldSettings.GameMode == GameMode.Cruel)
					{
						DialogsManager.ShowDialog(ComponentPlayer.GuiWidget, new GameMenuDialog(ComponentPlayer));
					}
					else if (m_subsystemGameInfo.WorldSettings.GameMode == GameMode.Adventure && !m_subsystemGameInfo.WorldSettings.IsAdventureRespawnAllowed)
					{
						ScreensManager.SwitchScreen("GameLoading", GameManager.WorldInfo, "AdventureRestart");
					}
					else
					{
						project.RemoveEntity(ComponentPlayer.Entity, disposeEntity: true);
					}
				}
			}, null);
			m_stateMachine.TransitionTo("FirstUpdate");
		}
	}
}
